package relu.fbs.xt;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import relu.fbs.BadDataException;
import relu.fbs.FarmData;
import relu.fbs.xt.FBSCropData.FBSCDatum;
import relu.fbs.xt.FBSFarmData.FBSFarmDatum;

public class FBS8898DataReader extends AbstractMultipleFileDataReader {
	enum FileType {
		CIR,
		A,
		LABOUR,
		CROPS;
	}
	
	static Map<Integer,FBSFarmData> read98Data() throws FileNotFoundException, IOException ,NumberFormatException,BadDataException{
		Map<FileType,String> fileMap = new HashMap<FileType,String>();
		fileMap.put(FileType.CIR, "h002cir.tab");
		fileMap.put(FileType.A, "h0021.tab");
		fileMap.put(FileType.LABOUR, "h0023.tab");
		fileMap.put(FileType.CROPS, "h0025.tab");
		return readData(fileMap,1);
	}
	static Map<Integer,FBSFarmData> read97Data() throws FileNotFoundException, IOException ,NumberFormatException,BadDataException{
		Map<FileType,String> fileMap = new HashMap<FileType,String>();
		fileMap.put(FileType.CIR, "h002cir.tab");
		fileMap.put(FileType.A, "h0021.tab");
		fileMap.put(FileType.LABOUR, "h0023.tab");
		fileMap.put(FileType.CROPS, "h0025.tab");
		return readData(fileMap,0);
	}
	static Map<Integer,FBSFarmData> read96Data() throws FileNotFoundException, IOException ,NumberFormatException,BadDataException{
		Map<FileType,String> fileMap = new HashMap<FileType,String>();
		fileMap.put(FileType.CIR, "g893cir.tab");
		fileMap.put(FileType.A, "g8931.tab");
		fileMap.put(FileType.LABOUR, "g8933.tab");
		fileMap.put(FileType.CROPS, "g8935.tab");
		return readData(fileMap,1);
	}
	static Map<Integer,FBSFarmData> read95Data() throws FileNotFoundException, IOException ,NumberFormatException,BadDataException{
		Map<FileType,String> fileMap = new HashMap<FileType,String>();
		fileMap.put(FileType.CIR, "g892cir.tab");
		fileMap.put(FileType.A, "g8921.tab");
		fileMap.put(FileType.LABOUR, "g8923.tab");
		fileMap.put(FileType.CROPS, "g8925.tab");
		return readData(fileMap,1);
	}
	static Map<Integer,FBSFarmData> read94Data() throws FileNotFoundException, IOException ,NumberFormatException,BadDataException{
		Map<FileType,String> fileMap = new HashMap<FileType,String>();
		fileMap.put(FileType.CIR, "g507cir.tab");
		fileMap.put(FileType.A, "g5071.tab");
		fileMap.put(FileType.LABOUR, "g5073.tab");
		fileMap.put(FileType.CROPS, "g5075.tab");
		return readData(fileMap,1);
	}
	static Map<Integer,FBSFarmData> read93Data() throws FileNotFoundException, IOException ,NumberFormatException,BadDataException{
		Map<FileType,String> fileMap = new HashMap<FileType,String>();
		fileMap.put(FileType.CIR, "g2268cir.tab");
		fileMap.put(FileType.A, "g22681.tab");
		fileMap.put(FileType.LABOUR, "g22683.tab");
		fileMap.put(FileType.CROPS, "g22685.tab");
		return readData(fileMap,1);
	}
	static Map<Integer,FBSFarmData> read92Data() throws FileNotFoundException, IOException ,NumberFormatException,BadDataException{
		Map<FileType,String> fileMap = new HashMap<FileType,String>();
		fileMap.put(FileType.CIR, "g2003cir.tab");
		fileMap.put(FileType.A, "g20031.tab");
		fileMap.put(FileType.LABOUR, "g20033.tab");
		fileMap.put(FileType.CROPS, "g20035.tab");
		return readData(fileMap,1);
	}
	static Map<Integer,FBSFarmData> read91Data() throws FileNotFoundException, IOException ,NumberFormatException,BadDataException{
		Map<FileType,String> fileMap = new HashMap<FileType,String>();
		fileMap.put(FileType.CIR, "f2945cir.tab");
		fileMap.put(FileType.A, "f29451.tab");
		fileMap.put(FileType.LABOUR, "f29453.tab");
		fileMap.put(FileType.CROPS, "f29455.tab");
		return readData(fileMap,1);
	}
	static Map<Integer,FBSFarmData> read90Data() throws FileNotFoundException, IOException ,NumberFormatException,BadDataException{
		Map<FileType,String> fileMap = new HashMap<FileType,String>();
		fileMap.put(FileType.CIR, "f2849cir.tab");
		fileMap.put(FileType.A, "f28491.tab");
		fileMap.put(FileType.LABOUR, "f28493.tab");
		fileMap.put(FileType.CROPS, "f28495.tab");
		return readData(fileMap,1);
	}
	static Map<Integer,FBSFarmData> read89Data() throws FileNotFoundException, IOException ,NumberFormatException,BadDataException{
		Map<FileType,String> fileMap = new HashMap<FileType,String>();
		fileMap.put(FileType.CIR, "f2719cir.tab");
		fileMap.put(FileType.A, "f27191.tab");
		fileMap.put(FileType.LABOUR, "f27193.tab");
		fileMap.put(FileType.CROPS, "f27195.tab");
		return readData(fileMap,1);
	}
	static Map<Integer,FBSFarmData> read88Data() throws FileNotFoundException, IOException ,NumberFormatException,BadDataException{
		Map<FileType,String> fileMap = new HashMap<FileType,String>();
		fileMap.put(FileType.CIR, "f2578cir.tab");
		fileMap.put(FileType.A, "f25781.tab");
		fileMap.put(FileType.LABOUR, "f25783.tab");
		fileMap.put(FileType.CROPS, "f25785.tab");
		return readData(fileMap,1);
	}

	
	static Map<Integer,FBSFarmData> readData(Map<FileType,String> fileNames,int yc) throws FileNotFoundException, IOException ,NumberFormatException,BadDataException {
		Map<Integer,FBSFarmData> farms = generateFarms(fileNames.get(FileType.CIR));
		String filetmp="";
		try {
		for(Map.Entry<FileType, String> file:fileNames.entrySet()){
			filetmp=file.getValue();
			FileType fn = file.getKey();
			System.out.println("Processing "+fn);
			switch(fn){
			case A:
				addAData(file.getValue(),farms,yc);
				break;
			case LABOUR:
				addLabourData(file.getValue(),farms,yc);
				break;
			case CROPS:
				addCropsData(file.getValue(),farms,yc);
				break;
			default:
				System.out.println("Skipped");
			}
		}				
		} catch (NumberFormatException ex){
			throw new NumberFormatException("Number format exception in file: "+filetmp+" "+ex.getMessage());
		}
		return farms;
	}
	
	
	static void addCropsData(String fileName,Map<Integer,FBSFarmData> farms,int yrcode) throws FileNotFoundException, IOException ,NumberFormatException,BadDataException {
		FileReader reader=new FileReader(fileName);
		BufferedReader buffrd=new BufferedReader(reader);

		String line = buffrd.readLine(); // Read the header 
		line=buffrd.readLine();
		while( line!=null){
			String[] colStrings=line.split("\t");
			int ycode=Integer.parseInt(colStrings[4]);
			if ( ycode==yrcode){
				int farmid = Integer.parseInt(colStrings[15]);				
				FBSFarmData theFarm=farms.get(farmid);

				int cropType = Integer.parseInt(colStrings[0]);
				double mainArea=Double.parseDouble(colStrings[5]);
				double multArea=Double.parseDouble(colStrings[6]);
				double subsidies=Double.parseDouble(colStrings[11]);
				double eo=Double.parseDouble(colStrings[12]);
				if ( FarmData.fbsTotalCodes.contains(cropType)){
//					System.out.println(cropType+" :"+farmid+" yc "+ycode+":"+yrcode);
					FBSDataReader.addSectionCTotal(theFarm, 
							new FBSPost2000DataPoint(farmid,'C',cropType,21,10,0),mainArea);
					FBSDataReader.addSectionCTotal(theFarm, 
							new FBSPost2000DataPoint(farmid,'C',cropType,40,10,0),subsidies);
					FBSDataReader.addSectionCTotal(theFarm, 
							new FBSPost2000DataPoint(farmid,'C',cropType,41,10,0),eo);
				} else {
					FBSCropData cropd = farms.get(farmid).getCrop(FarmData.getCheckedCropType(cropType));
				
					cropd.setDatum(FBSCDatum.AREA, mainArea, new FBSPost2000DataPoint(farmid,'C',cropType,-1,10,0));
					cropd.setDatum(FBSCDatum.MAREA, multArea, new FBSPost2000DataPoint(farmid,'C',cropType,-1,10,0));
//				double revXsubs=Double.parseDouble(colStrings[9]);
//				double farmCons=Double.parseDouble(colStrings[10]);
					cropd.setDatum(FBSCDatum.AREAPAYMENT, subsidies, new FBSPost2000DataPoint(farmid,'C',cropType,-1,10,0));
					cropd.setDatum(FBSCDatum.EO, eo, new FBSPost2000DataPoint(farmid,'C',cropType,-1,10,0));
				}
			}
			line=buffrd.readLine();
		}
	}

	static void addAData(String fileName,Map<Integer,FBSFarmData> farms,int yrcode) throws FileNotFoundException, IOException ,NumberFormatException,BadDataException {
		FileReader reader=new FileReader(fileName);
		BufferedReader buffrd=new BufferedReader(reader);

		String line = buffrd.readLine(); // Read the header 
		line=buffrd.readLine();
		Map<Integer,FBSFarmDatum> columnMap=new HashMap<Integer,FBSFarmDatum>();
		while( line!=null){
//			System.out.println(line);
			String[] colStrings=line.split("\t");
//			try {
			int ycode=Integer.parseInt(colStrings[3]);
			if ( ycode==yrcode){
				double region=Double.parseDouble(colStrings[0]);
				double county=Double.parseDouble(colStrings[1]);
				int farmid = Integer.parseInt(colStrings[2]);
				int Altitude=Integer.parseInt(colStrings[11]);
				int fob = Integer.parseInt(colStrings[7]);
				double tmsa=Double.parseDouble(colStrings[15]);
				double totalGrass=Double.parseDouble(colStrings[16]);
				double utilizedArea=Double.parseDouble(colStrings[17]);
				double nfincome = Double.parseDouble(colStrings[117]);
				if ( !colStrings[39].contentEquals(" ")){
					double saEligibleArea=Double.parseDouble(colStrings[39]);
					setDatum(farms,farmid,FBSFarmDatum.AREAELIGIBLEAAPS,saEligibleArea);
				} 
				if ( !colStrings[107].contentEquals(" ")){				
					double mainEO = Double.parseDouble(colStrings[107]);
					setDatum(farms,farmid,FBSFarmDatum.TOTALMAINEO,mainEO);
				}
				if ( !colStrings[141].contentEquals(" ")){
					double totalSAPayments=Double.parseDouble(colStrings[141]);
					setDatum(farms,farmid,FBSFarmDatum.SETASIDEPAYMENT,totalSAPayments);
				}
				setDatum(farms,farmid,FBSFarmDatum.ALTITUDE,(double)Altitude);
				setDatum(farms,farmid,FBSFarmDatum.TOTALMAINSETASIDE,tmsa);
				setDatum(farms,farmid,FBSFarmDatum.TOTALGRASS,totalGrass);
				setDatum(farms,farmid,FBSFarmDatum.UTILIZEDAREA,utilizedArea);
				setDatum(farms,farmid,FBSFarmDatum.FORMOFBUSINESS,fob);
				setDatum(farms,farmid,FBSFarmDatum.NETFARMINCOME,nfincome);
				setDatum(farms,farmid,FBSFarmDatum.REGION,(double)region);
				setDatum(farms,farmid,FBSFarmDatum.COUNTY,(double)county);

			}

//			} catch (NumberFormatException ex ){
//				throw new Error(":"+colStrings[39]+":");
//			}
			line=buffrd.readLine();
		}
	}
	
	
	static Map<Integer,FBSFarmData> generateFarms(String file) throws FileNotFoundException, IOException ,NumberFormatException, BadDataException {
		System.out.println("Generating Farms");
		Map<Integer,FBSFarmData> farms=new HashMap<Integer,FBSFarmData>();
		FileReader reader=new FileReader(file);
		BufferedReader buffrd=new BufferedReader(reader);
		String line = buffrd.readLine(); // Read the header 
		line=buffrd.readLine();
		while( line!=null){
			String[] colStrings=line.split("\t");
			int farmid=Integer.parseInt(colStrings[0]);
			if ( farms.containsKey(farmid)){
				throw new Error("Only one copy of each farm is allowed ");
			}
			FBSFarmData theFarm=new FBSFarmData(farmid);
			theFarm.putFarmData(FBSFarmDatum.FARMID, (double)farmid);
			farms.put(farmid, theFarm);
			line=buffrd.readLine();
		}
		return farms;
	}
}
